/**
 * @class 1つのオーディオユニットを定義するクラスです。
 *      インタフェースクラスなので、継承されることを前提としています。
 *      引数にAudioUnitを要求するメソッドに渡すオブジェクトは、ここで定義されている各メソッドを実装している必要があります。
 */
snd.AudioUnit = function() {
    // IT'S A INTERFACE CLASS
    // PLEASE OVERRIDE ALL METHODS
};

/**
 * 音源をこのユニットに接続します。
 *      渡される音源はAudioNodeクラスを継承するオブジェクトです。
 *      AudioUnitを継承するクラスは、このメソッド内で このユニットで定義される
 *      オーディオノードのチェーンの最初のノードへ引数で渡された音源を接続してください。
 *      AudioUnitの使用法によっては、多数の音源から複数回呼び出される可能性もあります。
 * @param {AudioNode} src 音源となるノードです(AudioBufferSourceNode, MediaElementAudioSourceNode, etc...)
 * @see {snd.GainOnlyUnit} snd.GainOnlyUnit ボリュームのみで構成された最も単純なAudioUnit
 */
snd.AudioUnit.prototype.connectSource = function(src) {
    // PLEASE OVERRIDE ME
};

/**
 * 渡された音源とこのユニットとの接続を切断します。
 *      渡される音源はAudioNodeクラスを継承するオブジェクトです。
 *      AudioUnitを継承するクラスは、このメソッド内で このユニットで定義される
 *      オーディオノードのチェーンの最初のノードと引数で渡された音源との接続を切断してください。
 *      AudioUnitの使用法によっては、多数の音源から複数回呼び出される可能性もあります。
 * @param {AudioNode} src ユニットから切断するAudioNode
 */
snd.AudioUnit.prototype.disconnectSource = function(src) {
    // PLEASE OVERRIDE ME
};

/**
 * 他のAudioNodeやAudioUnitと接続する際に使用されるAudioNodeを取得します。
 *      AudioUnitを継承するクラスは最終的な出力がでるAudioNodeを戻してください。
 * @returns {AudioNode} このユニットが他のAudioNodeやAudioUnitと接続する際に使われるAudioNode
 */
snd.AudioUnit.prototype.getConnector = function() {
    // PLEASE OVERRIDE ME
};

/*** GAIN ONLY UNIT ***/

/**
 * @class 主ボリュームのみの単純なユニットです。
 * @extends snd.AudioUnit
 */
snd.GainOnlyUnit = function() {
    snd.AudioUnit.apply(this, arguments);
    this.gain = snd.AUDIO_CONTEXT.createGain();
};
snd.GainOnlyUnit.prototype = Object.create(snd.AudioUnit.prototype);
snd.GainOnlyUnit.prototype.constructor = snd.GainOnlyUnit;

/**
 * @see snd.AudioUnit#connectSource
 * @param {AudioNode}
 */
snd.GainOnlyUnit.prototype.connectSource = function(src) {
    src.connect(this.gain);
};

/**
 * @see snd.AudioUnit#disconnectSource
 * @param {AudioNode}
 */
snd.GainOnlyUnit.prototype.disconnectSource = function(src) {
    src.disconnect(this.gain);
};

/**
 * @see snd.AudioUnit#getConnector
 */
snd.GainOnlyUnit.prototype.getConnector = function() {
    return this.gain;
};

/**
 * メインボリュームを取得します。
 *      ボリュームの使用法については<a href="http://g200kg.github.io/web-audio-api-ja/#GainNode">web audio api仕様のGainNode</a>を参照してください。
 * @returns {snd.GainNode} this.gain
 */
snd.GainOnlyUnit.prototype.getGain = function() {
    return this.gain;
};

